<?php

 /**
  * @package JooS
  * @subpackage CodeGenerator
  */

  require_once "JooS/CodeGenerator/Abstract.php";

  class JooS_CodeGenerator_Method extends JooS_CodeGenerator_Abstract {
    /**
     * @var bool
     */
    private $_final = false;

    /**
     * @var bool
     */
    private $_static = false;

    /**
     * @var string
     */
    private $_visibility = null;

    /**
     * @var array
     */
    private $_parameters;

    /**
     * @var string
     */
    private $_body = "";

    /**
     * @param string $name
     */
    protected function __construct($name) {
      parent::__construct($name);

      $this->setVisibility(self::VISIBILITY_PUBLIC);
      $this->clearParameters();
    }

    /**
     * @return string
     */
    public function compile() {
      $PHPCode = array();

      if ($this->isFinal()) {
        $PHPCode[] = "final";
      }

      $PHPCode[] = $this->_visibility;

      if ($this->isStatic()) {
        $PHPCode[] = "static";
      }

      $PHPCode[] = "function";

      $parameters = array();
      foreach ($this->getParameters() as $parameter) {
        /* @var $parameter JooS_CodeGenerator_Parameter */
        $parameters[] = $parameter->compile();
      }

      $PHPCode[] = $this->getName() . "(" . implode(",", $parameters) . ")";
      $PHPCode[] = "{";

      $body = $this->getBody();
      if ($body) {
        $PHPCode[] = $body;
      }
      $PHPCode[] = "}";

      return implode(" ", $PHPCode);
    }

    /**
     *
     * @param string $name
     * @return JooS_CodeGenerator_Method
     */
    public static function newInstance($name) {
      return new self($name);
    }

    /**
     * @param bool $final
     * @return JooS_CodeGenerator_Method
     */
    public function setFinal($final) {
      $this->_final = !!$final;
      return $this;
    }

    /**
     * @return bool
     */
    public function isFinal() {
      return $this->_final;
    }

    /**
     * @param bool $static
     * @return JooS_CodeGenerator_Method
     */
    public function setStatic($static) {
      $this->_static = !!$static;
      return $this;
    }

    /**
     * @return bool
     */
    public function isStatic() {
      return $this->_static;
    }

    /**
     * @param string $visibility
     * @return JooS_CodeGenerator_Method
     */
    public function setVisibility($visibility) {
      switch ($visibility) {
        case self::VISIBILITY_PUBLIC:
        case self::VISIBILITY_PROTECTED:
        case self::VISIBILITY_PRIVATE:
          $this->_visibility = $visibility;
          break;
        default:
          $this->_visibility = self::VISIBILITY_PUBLIC;
          break;
      }
      return $this;
    }

    /**
     * @return string
     */
    public function getVisibility() {
      return $this->_visibility;
    }

    /**
     * @param JooS_CodeGenerator_Parameter $parameter
     * @return JooS_CodeGenerator_Method
     */
    public function addParameter(JooS_CodeGenerator_Parameter $parameter) {
      $this->_parameters[] = $parameter;
      return $this;
    }

    /**
     * @return array
     */
    protected function getParameters() {
      return $this->_parameters;
    }

    /**
     * @return JooS_CodeGenerator_Method
     */
    public function clearParameters() {
      $this->_parameters = array();
      return $this;
    }

    /**
     * @param string $body
     * @return JooS_CodeGenerator_Method
     */
    public function setBody($body) {
      if (!is_string($body))
        trigger_error("Type mismatch", E_USER_NOTICE);
      else
        $this->_body = $body;

      return $this;
    }

    /**
     * @return string
     */
    public function getBody() {
      return $this->_body;
    }
  }
